package top.xiangqifu.springboot2.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import top.xiangqifu.springboot2.user.base.BaseDataResult;
import top.xiangqifu.springboot2.user.base.BasePageResult;
import top.xiangqifu.springboot2.user.base.BaseResult;
import top.xiangqifu.springboot2.user.base.PageBean;
import top.xiangqifu.springboot2.user.dao.TbFileDAO;
import top.xiangqifu.springboot2.user.entity.AuthInfo;
import top.xiangqifu.springboot2.user.entity.TbFile;
import top.xiangqifu.springboot2.user.service.FileService;
import top.xiangqifu.springboot2.user.utils.AuthInfoUtils;
import top.xiangqifu.springboot2.user.utils.JsonUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.List;

@Service
@RequiredArgsConstructor
@Slf4j
public class FileServiceImpl implements FileService {
    private final TbFileDAO tbFileDAO;

    public static final String URLOAD_PATH = "./files/";
    public static final int BUFF_SIZE = 8*1024;

    public static final String FILE_INFO = "用户图片";
    private static final String FILE_NAME="_%s_%s";
    public void copy(InputStream is, OutputStream out){
        byte[] bytes=new byte[BUFF_SIZE];
        try {
            int len=is.read(bytes);
            while (len>0){
                out.write(bytes,0,len);
                out.flush();
                len=is.read(bytes);
            }
            out.close();
            is.close();
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }


    @Override
    public void download(Integer fid, HttpServletResponse response){
        //查询文件信息
        TbFile tbFile=tbFileDAO.selectById(fid);
        BaseResult result;
        if (tbFile==null){
            result=BaseResult.fail("文件不存在");
            try {
                response.reset();;
                response.setContentType("text/plain;charset=UTF-8");
                response.getWriter().write(JsonUtils.stringify(result));
                response.getWriter().flush();
                response.getWriter().close();
                return;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        //自定义应答
        String fileName=String.format(FILE_NAME,fid, tbFile.getFileName());
        File file=new File(URLOAD_PATH,fileName);
        response.reset();;
        response.setContentType(tbFile.getContentType());
        byte[] filenamebytes=fileName.getBytes(StandardCharsets.UTF_8);
        response.setHeader("Content-Disposition", "attachment;filename="+
                new String(filenamebytes,0, filenamebytes.length, StandardCharsets.ISO_8859_1));
        try {
            copy(new FileInputStream(file),response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    @Override
    @Transactional
    public BaseDataResult<TbFile> upload(TbFile tbFile, MultipartFile fileinfo){
        AuthInfo authInfo= AuthInfoUtils.authInfo();
        //保存文件信息到数据库
        tbFile.setUid(authInfo.getUid());
        tbFile.setFileName(fileinfo.getOriginalFilename());
        tbFile.setFileSize(fileinfo.getSize());
        tbFile.setContentType(fileinfo.getContentType());
        int r=tbFileDAO.insert(tbFile);
        if (r!=1){
            return BaseDataResult.failNoData("保存文件信息失败");
        }
        //保存文件
        File path=new File(URLOAD_PATH);
        File file=new File(URLOAD_PATH,String.format(FILE_NAME,tbFile.getFid(),tbFile.getFileName()));
        try {

            if (!path.isDirectory()){
                //确保文件所在目录存在
                path.mkdirs();
            }
            copy(fileinfo.getInputStream(),new FileOutputStream(file));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return BaseDataResult.ok(tbFile);
    }

    @Override
    public BasePageResult<List<TbFile>> historyFile(PageBean pageBean){
        TbFile tbFile=new TbFile();
        AuthInfo authInfo=AuthInfoUtils.authInfo();
        tbFile.setUid(authInfo.getUid());
        tbFile.setInfo(FILE_INFO);
        QueryWrapper<TbFile> wrapper = new QueryWrapper<>();
        wrapper.select("fid","uid","file_name", "info", "file_size", "content_type");
        // 标题模糊查询
        wrapper.like(StringUtils.hasText(tbFile.getFileName()), "fileName", tbFile.getFileName());
        wrapper.eq(tbFile.getUid() != null, "uid", tbFile.getUid());
        wrapper.eq(StringUtils.hasText(tbFile.getInfo()), "info", tbFile.getInfo());
        // 分页查询
        IPage<TbFile> page = PageBean.buildPageInfo(pageBean, TbFile.class);
        page = tbFileDAO.selectPage(page, wrapper);
        return BasePageResult.ok(pageBean.populate(page), page.getRecords());
    }

    @Override
    public BasePageResult<List<TbFile>> queryUserFile(TbFile tbFile, PageBean pageBean){
        AuthInfo authInfo=AuthInfoUtils.authInfo();
        tbFile.setUid(authInfo.getUid());
        QueryWrapper<TbFile> wrapper = new QueryWrapper<>();
        wrapper.select("fid","uid","file_name", "info", "file_size", "content_type","created");
        // 标题模糊查询
        wrapper.like(StringUtils.hasText(tbFile.getFileName()), "fileName", tbFile.getFileName());
        wrapper.like(StringUtils.hasText(tbFile.getInfo()), "info", tbFile.getInfo());
        wrapper.like(StringUtils.hasText(tbFile.getContentType()), "contentType", tbFile.getContentType());
        wrapper.eq(tbFile.getUid() != null, "uid", tbFile.getUid());
        // 分页查询
        IPage<TbFile> page = PageBean.buildPageInfo(pageBean, TbFile.class);
        page = tbFileDAO.selectPage(page, wrapper);
        return BasePageResult.ok(pageBean.populate(page), page.getRecords());
    }
}
